﻿using System.IO;
using UnityEngine;

namespace Core.Res
{
    public partial class BundleLoader
    {
        public class Bundle : LoadAwaiter
        {
            private readonly BundleLoader loader;

            private AssetBundleCreateRequest mRequest;

            public AssetBundle Ab { get; private set; }
            private BundleInfo bundleInfo;

            public Bundle(BundleLoader loader) : base(loader)
            {
                this.loader = loader;
            }

            public void SetInfo(string bundle_name)
            {
                //bundleInfo = info;
                bundleInfo = loader.ResDict.GetBundle(bundle_name);
            }

            public override void Start()
            {
                if (loader.bundles.ContainsKey(Name))
                {
                    State = ELoadState.Complete;
                    return;
                }
                State = ELoadState.Loading;
                Progress = 0;

                var path = Path.Combine(loader.ROPath, bundleInfo.MD5);
                mRequest = AssetBundle.LoadFromFileAsync(path, 0, (ulong)bundleInfo.Position);
            }

            public override void Update()
            {
                if (State != ELoadState.Loading || mRequest == null)
                {
                    return;
                }

                if (mRequest.isDone)
                {
                    if (mRequest.progress == 0)
                    {
                        Start();
                        return;
                    }

                    Ab = mRequest.assetBundle;
                    Progress = 1;
                    State = ELoadState.Complete;
                    loader.bundles[Name] = this;
                }
                else if (!Mathf.Approximately(mRequest.progress, Progress))
                {
                    Progress = mRequest.progress;
                }
            }

            public override void Finish()
            {
                mRequest = null;

                Awaiter?.SetResult();
            }

            public void Dispose()
            {
                State = ELoadState.Invalid;
                if (Ab != null)
                {
                    Ab.Unload(true);
                    Ab = null;
                }
            }

            public void LoadSync()
            {
                Ab = AssetBundle.LoadFromFile(Name);

                loader.bundles[Name] = this;
                loader.missing.Remove(Name);
            }
        }
    }
}
